"""
项目管理API路由
"""
from typing import Any, List, Optional, Dict
from fastapi import APIRouter, Depends, HTTPException, status, Query, Request
from motor.motor_asyncio import AsyncIOMotorDatabase
from bson import ObjectId
from datetime import datetime, timedelta
import logging

# 设置日志记录器
logger = logging.getLogger(__name__)

from app.api.deps import get_db, get_current_user
from app.services.project_service import (
    project_service
)
from app.utils.task_utils import calculate_project_progress
from app.utils.state_utils import (
    validate_state_code,
    get_completed_state_code,
    get_active_state_code,
    get_state_options,
    get_state_code_by_name_keywords
)
from app.core.response import success_response, error_response, paginated_response, ErrorTypes, ErrorMessages, ApiResponse
from app.models.project import (
    ProjectCreate, 
    ProjectUpdate, 
    ProjectMemberAdd,
    ProjectMemberUpdate,
    ProjectCategory,
    ProjectMemberRole
)
from app.core.permissions import Permissions
from app.services.notification_service import NotificationService
from app.models.notification import NotificationCreate, NotificationType, RelatedObjectType
import asyncio

router = APIRouter()

@router.get("/", response_model=None, summary="获取项目列表（分页）")
async def get_projects(
    request: Request,
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(10, ge=1, le=100, description="返回的记录数"),
    page: Optional[int] = Query(None, ge=1, description="页码（兼容性参数）"),
    size: Optional[int] = Query(None, ge=1, le=200, description="每页大小（兼容性参数）"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    status: Optional[str] = Query(None, description="项目状态"),
    priority: Optional[str] = Query(None, description="项目优先级"),
    category: Optional[ProjectCategory] = Query(None, description="项目分类"),
    created_by: Optional[str] = Query(None, description="创建者ID"),
    member_id: Optional[str] = Query(None, description="成员ID"),
    is_archived: Optional[bool] = Query(None, description="是否归档"),
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目列表
    """
    try:
        # 处理兼容性参数：如果提供了page和size，转换为skip和limit
        if page is not None and size is not None:
            skip = (page - 1) * size
            limit = size
        
        # 使用服务层获取项目列表
        result, total = await project_service.get_projects_list(
            db=db,
            current_user=current_user,
            skip=skip,
            limit=limit,
            search=search,
            status=status,
            priority=priority,
            category=category,
            created_by=created_by,
            member_id=member_id,
            is_archived=is_archived
        )
        
        return paginated_response(
            items=result,
            total=total,
            page=skip // limit + 1,
            size=limit,
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except ValueError as e:
        return error_response(
            error_type=ErrorTypes.VALIDATION_ERROR,
            message=str(e),
            code=400,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        import traceback
        print(f"Error in get_projects: {str(e)}")
        print(f"Traceback: {traceback.format_exc()}")
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取项目列表失败: {str(e)}",
            request_id=getattr(request.state, 'request_id', None)
        )

@router.get("/count", response_model=ApiResponse, summary="获取项目总数")
async def get_projects_count(
    request: Request,
    search: Optional[str] = Query(None, description="搜索关键词"),
    status: Optional[str] = Query(None, description="项目状态筛选"),
    priority: Optional[str] = Query(None, description="优先级筛选"),
    category: Optional[ProjectCategory] = Query(None, description="分类筛选"),
    created_by: Optional[str] = Query(None, description="创建者筛选"),
    member_id: Optional[str] = Query(None, description="成员筛选"),
    is_archived: Optional[bool] = Query(None, description="是否归档筛选"),
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目总数
    """
    # 构建查询条件（与get_projects相同的逻辑）
    query = {}
    
    # 权限控制
    user_permissions = current_user.get("permissions", [])
    if Permissions.PROJECT_READ_ALL not in user_permissions and Permissions.ADMIN not in user_permissions:
        query["$or"] = [
            {"is_public": True},
            {"created_by": ObjectId(current_user.get("user_id"))},
            {"members.user_id": ObjectId(current_user.get("user_id"))}
        ]
    
    if search:
        query["$and"] = query.get("$and", [])
        query["$and"].append({
            "$or": [
                {"name": {"$regex": search, "$options": "i"}},
                {"description": {"$regex": search, "$options": "i"}},
                {"tags": {"$in": [{"$regex": search, "$options": "i"}]}}
            ]
        })
    
    if status:
        # 验证状态代码是否有效
        is_valid = await validate_state_code(db, "project", status)
        if not is_valid:
            return error_response(
                error_type=ErrorTypes.INVALID_PARAMETER,
                message=f"Invalid status value: {status}",
                code=400,
                request_id=getattr(request.state, 'request_id', None)
            )
        query["status"] = status
    
    # 验证优先级（从priorities集合中验证）
    if priority:
        if priority == "":
            priority = None
        else:
            priority_doc = await db.priorities.find_one({
                "module_type": "project",
                "code": priority,
                "is_enabled": True
            })
            if not priority_doc:
                return error_response(
                    error_type=ErrorTypes.INVALID_PARAMETER,
                    message=f"Invalid priority value: {priority}",
                    code=400,
                    request_id=getattr(request.state, 'request_id', None)
                )
            query["priority"] = priority
    
    if category:
        query["category"] = category
    
    if created_by:
        try:
            query["created_by"] = ObjectId(created_by)
        except Exception:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid created_by ID format"
            )
    
    if member_id:
        try:
            query["members.user_id"] = ObjectId(member_id)
        except Exception:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid member_id format"
            )
    
    if is_archived is not None:
        query["is_archived"] = is_archived
    
    # 统计总数
    total = await db.projects.count_documents(query)
    return success_response(data={"total": total})

@router.get("/stats/dashboard", response_model=ApiResponse, summary="获取项目仪表盘数据")
async def get_project_dashboard_stats(
    request: Request,
    start_date: Optional[str] = Query(None, description="开始日期（YYYY-MM-DD）"),
    end_date: Optional[str] = Query(None, description="结束日期（YYYY-MM-DD）"),
    period: Optional[str] = Query("month", description="趋势周期：week/month/quarter"),
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目仪表盘图表数据
    包括：进度分布、状态分布、创建趋势、团队效率排行
    """
    try:
        # 使用服务层获取仪表盘数据
        dashboard_data = await project_service.get_dashboard_stats(
            db=db,
            current_user=current_user,
            start_date=start_date,
            end_date=end_date,
            period=period or "month"
        )
        
        return success_response(
            data=dashboard_data,
            message="Project dashboard statistics retrieved successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except Exception as e:
        logger.error(f"获取项目仪表盘数据失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.get("/{project_id}", response_model=ApiResponse, summary="获取项目详情")
async def get_project(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目详情
    """
    # 防止路由冲突：如果project_id是保留路径，返回404
    reserved_paths = ["stats", "versions", "dashboard", "list", "create", "count"]
    if project_id in reserved_paths:
        return error_response(
            error_type=ErrorTypes.NOT_FOUND,
            message="Project not found",
            code=404,
            request_id=getattr(request.state, 'request_id', None)
        )
    
    try:
        project_data = await project_service.get_project_by_id(
            db=db,
            project_id=project_id,
            current_user=current_user
        )
        
        return success_response(
            data=project_data,
            message="Project retrieved successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
    except ValueError as e:
        return error_response(
            error_type=ErrorTypes.NOT_FOUND,
            message=str(e),
            code=404,
            request_id=getattr(request.state, 'request_id', None)
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        logger.error(f"获取项目详情失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.post("/", response_model=ApiResponse, summary="创建项目")
async def create_project(
    request: Request,
    project_in: ProjectCreate,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    创建项目
    """
    try:
        project_data = await project_service.create_project(
            db=db,
            project_in=project_in,
            current_user=current_user
        )
        
        # 触发通知：项目创建时通知项目成员
        try:
            project_id = project_data.get("id")
            if project_id:
                # 获取创建的项目信息
                project = await db.projects.find_one({"_id": ObjectId(project_id)})
                if project:
                    current_user_obj = await db.users.find_one({"_id": ObjectId(current_user.get("user_id"))})
                    current_user_name = current_user_obj.get("name") or current_user_obj.get("username", "系统") if current_user_obj else "系统"
                    project_name = project.get("name", "项目")
                    
                    # 获取项目成员列表（排除当前用户）
                    members = project.get("members", [])
                    user_id = ObjectId(current_user.get("user_id"))
                    
                    # 通知所有项目成员（除了当前用户）
                    notification_tasks = []
                    for member in members:
                        member_user_id = member.get("user_id")
                        if member_user_id and member_user_id != user_id:
                            notification_data = NotificationCreate(
                                user_id=str(member_user_id),
                                type=NotificationType.PROJECT_CREATED,
                                title=f"新项目创建：{project_name}",
                                content=f"{current_user_name} 创建了项目「{project_name}」，您已被添加为项目成员",
                                related_type=RelatedObjectType.PROJECT,
                                related_id=project_id
                            )
                            notification_tasks.append(
                                NotificationService.create_notification(
                                    db=db,
                                    notification_data=notification_data,
                                    send_email=False
                                )
                            )
                    
                    # 异步发送所有通知
                    if notification_tasks:
                        asyncio.create_task(asyncio.gather(*notification_tasks, return_exceptions=True))
        except Exception as e:
            logger.warning(f"发送项目创建通知失败: {str(e)}")
        
        return success_response(
            data=project_data,
            message="Project created successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403,
            request_id=getattr(request.state, 'request_id', None)
        )
    except ValueError as e:
        return error_response(
            error_type=ErrorTypes.VALIDATION_ERROR,
            message=str(e),
            code=400,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        logger.error(f"创建项目失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.put("/{project_id}", response_model=ApiResponse, summary="更新项目")
async def update_project(
    request: Request,
    project_id: str,
    project_in: ProjectUpdate,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    更新项目信息
    """
    try:
        # 获取更新前的项目信息
        project_object_id = ObjectId(project_id)
        old_project = await db.projects.find_one({"_id": project_object_id})
        
        project_data = await project_service.update_project(
            db=db,
            project_id=project_id,
            project_in=project_in,
            current_user=current_user
        )
        
        # 触发通知：项目更新时通知项目成员
        if old_project:
            try:
                current_user_obj = await db.users.find_one({"_id": ObjectId(current_user.get("user_id"))})
                current_user_name = current_user_obj.get("name") or current_user_obj.get("username", "系统") if current_user_obj else "系统"
                project_name = old_project.get("name", "项目")
                
                # 获取项目成员列表（排除当前用户）
                members = old_project.get("members", [])
                user_id = ObjectId(current_user.get("user_id"))
                
                # 通知所有项目成员（除了当前用户）
                notification_tasks = []
                for member in members:
                    member_user_id = member.get("user_id")
                    if member_user_id and member_user_id != user_id:
                        notification_data = NotificationCreate(
                            user_id=str(member_user_id),
                            type=NotificationType.PROJECT_UPDATED,
                            title=f"项目更新：{project_name}",
                            content=f"{current_user_name} 更新了项目「{project_name}」",
                            related_type=RelatedObjectType.PROJECT,
                            related_id=project_id
                        )
                        notification_tasks.append(
                            NotificationService.create_notification(
                                db=db,
                                notification_data=notification_data,
                                send_email=False
                            )
                        )
                
                # 异步发送所有通知
                if notification_tasks:
                    asyncio.create_task(asyncio.gather(*notification_tasks, return_exceptions=True))
            except Exception as e:
                logger.warning(f"发送项目更新通知失败: {str(e)}")
        
        return success_response(
            data=project_data,
            message="Project updated successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
    except ValueError as e:
        status_code = 404 if "not found" in str(e).lower() else 400
        return error_response(
            error_type=ErrorTypes.VALIDATION_ERROR if status_code == 400 else ErrorTypes.NOT_FOUND,
            message=str(e),
            code=status_code,
            request_id=getattr(request.state, 'request_id', None)
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        logger.error(f"更新项目失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.post("/{project_id}/archive", response_model=ApiResponse, summary="归档项目")
async def archive_project(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    归档项目
    """
    try:
        project_data = await project_service.archive_project(
            db=db,
            project_id=project_id,
            current_user=current_user
        )
        
        return success_response(
            data=project_data,
            message="Project archived successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
    except ValueError as e:
        status_code = 404 if "not found" in str(e).lower() else 400
        return error_response(
            error_type=ErrorTypes.NOT_FOUND if status_code == 404 else ErrorTypes.VALIDATION_ERROR,
            message=str(e),
            code=status_code,
            request_id=getattr(request.state, 'request_id', None)
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        logger.error(f"归档项目失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.post("/{project_id}/unarchive", response_model=ApiResponse, summary="取消归档项目")
async def unarchive_project(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    取消归档项目（恢复项目）
    """
    try:
        project_data = await project_service.unarchive_project(
            db=db,
            project_id=project_id,
            current_user=current_user
        )
        
        return success_response(
            data=project_data,
            message="Project unarchived successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
    except ValueError as e:
        status_code = 404 if "not found" in str(e).lower() else 400
        return error_response(
            error_type=ErrorTypes.NOT_FOUND if status_code == 404 else ErrorTypes.VALIDATION_ERROR,
            message=str(e),
            code=status_code,
            request_id=getattr(request.state, 'request_id', None)
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403,
            request_id=getattr(request.state, 'request_id', None)
        )
    except Exception as e:
        logger.error(f"取消归档项目失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.delete("/{project_id}", response_model=ApiResponse, summary="删除（归档）项目")
async def delete_project(
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    删除项目（软删除：归档）
    """
    try:
        # 获取删除前的项目信息（用于通知）
        project_object_id = ObjectId(project_id)
        old_project = await db.projects.find_one({"_id": project_object_id})
        
        await project_service.delete_project(
            db=db,
            project_id=project_id,
            current_user=current_user
        )
        
        # 触发通知：项目删除时通知项目成员
        if old_project:
            try:
                current_user_obj = await db.users.find_one({"_id": ObjectId(current_user.get("user_id"))})
                current_user_name = current_user_obj.get("name") or current_user_obj.get("username", "系统") if current_user_obj else "系统"
                project_name = old_project.get("name", "项目")
                
                # 获取项目成员列表（排除当前用户）
                members = old_project.get("members", [])
                user_id = ObjectId(current_user.get("user_id"))
                
                # 通知所有项目成员（除了当前用户）
                notification_tasks = []
                for member in members:
                    member_user_id = member.get("user_id")
                    if member_user_id and member_user_id != user_id:
                        notification_data = NotificationCreate(
                            user_id=str(member_user_id),
                            type=NotificationType.PROJECT_DELETED,
                            title=f"项目已删除：{project_name}",
                            content=f"{current_user_name} 删除了项目「{project_name}」",
                            related_type=RelatedObjectType.PROJECT,
                            related_id=project_id
                        )
                        notification_tasks.append(
                            NotificationService.create_notification(
                                db=db,
                                notification_data=notification_data,
                                send_email=False
                            )
                        )
                
                # 异步发送所有通知
                if notification_tasks:
                    asyncio.create_task(asyncio.gather(*notification_tasks, return_exceptions=True))
            except Exception as e:
                logger.warning(f"发送项目删除通知失败: {str(e)}")
        
        return success_response(
            data={"id": project_id},
            message="Project deleted successfully"
        )
    except ValueError as e:
        status_code = 404 if "not found" in str(e).lower() else 400
        return error_response(
            error_type=ErrorTypes.NOT_FOUND if status_code == 404 else ErrorTypes.VALIDATION_ERROR,
            message=str(e),
            code=status_code
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=403
        )
    except Exception as e:
        logger.error(f"删除项目失败: {str(e)}", exc_info=True)
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR
        )

@router.get("/{project_id}/members", response_model=ApiResponse, summary="获取项目成员列表")
async def get_project_members(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目成员列表
    """
    # 防止路由冲突：如果project_id是保留路径，返回404
    reserved_paths = ["stats", "versions", "dashboard", "list", "create", "count"]
    if project_id in reserved_paths:
        return error_response(
            error_type=ErrorTypes.NOT_FOUND,
            message="Project not found",
            code=404,
            request_id=getattr(request.state, 'request_id', None)
        )
    # 验证ObjectId格式
    try:
        object_id = ObjectId(project_id)
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid project ID format"
        )
    
    # 检查项目是否存在
    project = await db.projects.find_one({"_id": object_id})
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found"
        )
    
    # 检查项目成员权限
    from app.services.permission_service import PermissionService
    try:
        project_id_str = str(object_id) if isinstance(object_id, ObjectId) else project_id
        has_access = await PermissionService.check_project_member_permission(
            project_id_str,
            current_user,
            db,
            "project:read"
        )
        if not has_access:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Not enough permissions to view project members"
            )
    except HTTPException:
        raise
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to view project members"
        )
    
    # 使用聚合管道获取成员详细信息
    pipeline = [
        {
            "$match": {"_id": object_id}
        },
        {
            "$unwind": "$members"
        },
        {
            "$lookup": {
                "from": "users",
                "localField": "members.user_id",
                "foreignField": "_id",
                "as": "members.user_info"
            }
        },
        {
            "$unwind": "$members.user_info"
        },
        {
            "$group": {
                "_id": "$_id",
                "name": {"$first": "$name"},
                "members": {
                    "$push": {
                        "user_id": "$members.user_id",
                        "roles": "$members.roles",
                        "joined_at": "$members.joined_at",
                        "permissions": "$members.permissions",
                        "username": "$members.user_info.username",
                        "email": "$members.user_info.email",
                        "name": "$members.user_info.name",
                        "avatar": "$members.user_info.avatar",
                        "is_active": "$members.user_info.status"
                    }
                }
            }
        }
    ]
    
    result = await db.projects.aggregate(pipeline).to_list(length=1)
    
    if not result:
        # 如果项目没有成员，则返回空列表
        return success_response(
            data={
                "project_id": str(project["_id"]),
                "project_name": project.get("name"),
                "members": [],
                "total_members": 0
            },
            message="Project members retrieved successfully",
            request_id=getattr(request.state, 'request_id', None)
        )

    project_data = result[0]
    members_data = project_data.get("members", [])

    # 格式化成员数据
    for member in members_data:
        member["user_id"] = str(member["user_id"])
        member["is_active"] = member["is_active"] == "active"

    return success_response(
        data={
            "project_id": str(project["_id"]),
            "project_name": project.get("name"),
            "members": members_data,
            "total_members": len(members_data)
        },
        message="Project members retrieved successfully",
        request_id=getattr(request.state, 'request_id', None)
    )

@router.post("/{project_id}/members", response_model=ApiResponse, summary="添加项目成员")
async def add_project_member(
    project_id: str,
    member_in: ProjectMemberAdd,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    添加项目成员
    """
    # 验证ObjectId格式
    try:
        object_id = ObjectId(project_id)
        user_object_id = ObjectId(member_in.user_id)
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid ID format"
        )
    
    # 检查项目是否存在
    project = await db.projects.find_one({"_id": object_id})
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found"
        )
    
    # 权限检查
    user_permissions = current_user.get("permissions", [])
    user_id = ObjectId(current_user.get("user_id"))
    
    # 检查是否有权限管理项目成员
    has_permission = (
        Permissions.PROJECT_MANAGE_MEMBERS in user_permissions or
        Permissions.ADMIN in user_permissions or
        project["created_by"] == user_id or
        any(
            member["user_id"] == user_id and "project:manage_members" in member.get("permissions", [])
            for member in project.get("members", [])
        )
    )
    
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to manage project members"
        )
    
    # 检查用户是否存在
    user = await db.users.find_one({"_id": user_object_id})
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    
    # 检查用户是否已是项目成员
    existing_member = any(
        member["user_id"] == user_object_id
        for member in project.get("members", [])
    )
    
    if existing_member:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="User is already a project member"
        )
    
    # 添加成员
    new_member = {
        "user_id": user_object_id,
        "roles": member_in.roles,
        "joined_at": datetime.utcnow(),
        "permissions": member_in.permissions
    }
    
    await db.projects.update_one(
        {"_id": object_id},
        {
            "$push": {"members": new_member},
            "$set": {"updated_at": datetime.utcnow()}
        }
    )
    
    return success_response(message="Member added successfully")

@router.put("/{project_id}/members/{user_id}", response_model=ApiResponse, summary="更新项目成员")
async def update_project_member(
    project_id: str,
    user_id: str,
    member_in: ProjectMemberUpdate,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    更新项目成员信息
    """
    # 验证ObjectId格式
    try:
        project_object_id = ObjectId(project_id)
        user_object_id = ObjectId(user_id)
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid ID format"
        )
    
    # 检查项目是否存在
    project = await db.projects.find_one({"_id": project_object_id})
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found"
        )
    
    # 权限检查
    user_permissions = current_user.get("permissions", [])
    current_user_id = ObjectId(current_user.get("user_id"))
    
    # 检查是否有权限管理项目成员
    has_permission = (
        Permissions.PROJECT_MANAGE_MEMBERS in user_permissions or
        Permissions.ADMIN in user_permissions or
        project["created_by"] == current_user_id or
        any(
            member["user_id"] == current_user_id and "project:manage_members" in member.get("permissions", [])
            for member in project.get("members", [])
        )
    )
    
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to manage project members"
        )
    
    # 检查成员是否存在
    member_exists = any(
        member["user_id"] == user_object_id
        for member in project.get("members", [])
    )
    
    if not member_exists:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Member not found in project"
        )
    
    # 构建更新数据
    update_data = member_in.model_dump(exclude_unset=True)
    
    # 更新成员信息
    update_fields = {}
    for field, value in update_data.items():
        update_fields[f"members.$.{field}"] = value
    
    if update_fields:
        await db.projects.update_one(
            {"_id": project_object_id, "members.user_id": user_object_id},
            {
                "$set": {
                    **update_fields,
                    "updated_at": datetime.utcnow()
                }
            }
        )
    
    return success_response(message="Member updated successfully")

@router.delete("/{project_id}/members/{user_id}", response_model=ApiResponse, summary="移除项目成员")
async def remove_project_member(
    project_id: str,
    user_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    移除项目成员
    """
    # 验证ObjectId格式
    try:
        project_object_id = ObjectId(project_id)
        user_object_id = ObjectId(user_id)
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid ID format"
        )
    
    # 检查项目是否存在
    project = await db.projects.find_one({"_id": project_object_id})
    if not project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project not found"
        )
    
    # 权限检查
    user_permissions = current_user.get("permissions", [])
    current_user_id = ObjectId(current_user.get("user_id"))
    
    # 检查是否有权限管理项目成员
    has_permission = (
        Permissions.PROJECT_MANAGE_MEMBERS in user_permissions or
        Permissions.ADMIN in user_permissions or
        project["created_by"] == current_user_id or
        any(
            member["user_id"] == current_user_id and "project:manage_members" in member.get("permissions", [])
            for member in project.get("members", [])
        )
    )
    
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions to manage project members"
        )
    
    # 不能移除项目创建者
    if project["created_by"] == user_object_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Cannot remove project creator"
        )
    
    # 移除成员
    result = await db.projects.update_one(
        {"_id": project_object_id},
        {
            "$pull": {"members": {"user_id": user_object_id}},
            "$set": {"updated_at": datetime.utcnow()}
        }
    )
    
    if result.modified_count == 0:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Member not found in project"
        )
    
    return success_response(message="Member removed successfully")

@router.get("/stats/summary", response_model=ApiResponse, summary="获取项目统计摘要")
async def get_project_stats_summary(
    request: Request,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目统计摘要
    返回基础的项目统计信息：总数、进行中、已完成、逾期项目数
    """
    try:
        # 构建查询条件（基于用户权限）
        query = {}
        user_permissions = current_user.get("permissions", [])
        if Permissions.PROJECT_READ_ALL not in user_permissions and Permissions.ADMIN not in user_permissions:
            query["$or"] = [
                {"is_public": True},
                {"created_by": ObjectId(current_user.get("user_id"))},
                {"members.user_id": ObjectId(current_user.get("user_id"))}
            ]
        
        # 排除归档项目（统计不包含归档项目）
        query["is_archived"] = {"$ne": True}
        
        # 统计项目总数
        total_projects = await db.projects.count_documents(query)
        
        # 获取活跃和已完成状态码
        active_status_code = await get_active_state_code(db, "project")
        completed_status_code = await get_completed_state_code(db, "project")
        
        # 统计活跃项目数
        active_projects = 0
        if active_status_code:
            active_query = {**query, "status": active_status_code}
            active_projects = await db.projects.count_documents(active_query)
        
        # 统计已完成项目数
        completed_projects = 0
        if completed_status_code:
            completed_query = {**query, "status": completed_status_code}
            completed_projects = await db.projects.count_documents(completed_query)
        
        # 统计逾期项目数（状态为ACTIVE且结束日期小于当前时间且结束日期不为空）
        current_time = datetime.utcnow()
        overdue_projects = 0
        if active_status_code:
            overdue_query = {
                **query, 
                "status": active_status_code,
                "end_date": {"$lt": current_time, "$ne": None}
            }
            overdue_projects = await db.projects.count_documents(overdue_query)
        
        # 统计归档项目数（包含归档项目）
        archived_query = {}
        if Permissions.PROJECT_READ_ALL not in user_permissions and Permissions.ADMIN not in user_permissions:
            archived_query["$or"] = [
                {"is_public": True},
                {"created_by": ObjectId(current_user.get("user_id"))},
                {"members.user_id": ObjectId(current_user.get("user_id"))}
            ]
        archived_query["is_archived"] = True
        archived_projects = await db.projects.count_documents(archived_query)
        
        stats_data = {
            "total_projects": total_projects,
            "active_projects": active_projects,
            "completed_projects": completed_projects,
            "overdue_projects": overdue_projects,
            "archived_projects": archived_projects
        }
        
        return success_response(
            data=stats_data,
            message="Project statistics summary retrieved successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.get("/stats/overview", response_model=ApiResponse, summary="获取项目统计概览")
async def get_project_stats(
    request: Request,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """
    获取项目统计概览
    """
    try:
        # 构建查询条件（基于用户权限）
        query = {}
        user_permissions = current_user.get("permissions", [])
        if Permissions.PROJECT_READ_ALL not in user_permissions and Permissions.ADMIN not in user_permissions:
            query["$or"] = [
                {"is_public": True},
                {"created_by": ObjectId(current_user.get("user_id"))},
                {"members.user_id": ObjectId(current_user.get("user_id"))}
            ]
        
        # 排除归档项目（统计不包含归档项目）
        query["is_archived"] = {"$ne": True}
        
        # 获取状态代码
        active_status_code = await get_active_state_code(db, "project")
        completed_status_code = await get_completed_state_code(db, "project")
        
        # 统计项目总数
        total_projects = await db.projects.count_documents(query)
        
        # 统计活跃项目数
        active_projects = 0
        if active_status_code:
            active_query = {**query, "status": active_status_code}
            active_projects = await db.projects.count_documents(active_query)
        
        # 统计已完成项目数
        completed_projects = 0
        if completed_status_code:
            completed_query = {**query, "status": completed_status_code}
            completed_projects = await db.projects.count_documents(completed_query)
        
        # 统计逾期项目数（状态为ACTIVE且结束日期小于当前时间且结束日期不为空）
        current_time = datetime.utcnow()
        overdue_projects = 0
        if active_status_code:
            overdue_query = {
                **query, 
                "status": active_status_code,
                "end_date": {"$lt": current_time, "$ne": None}
            }
            overdue_projects = await db.projects.count_documents(overdue_query)
        
        # 按状态分组统计
        pipeline = [
            {"$match": query},
            {"$group": {"_id": "$status", "count": {"$sum": 1}}}
        ]
        status_stats = await db.projects.aggregate(pipeline).to_list(length=None)
        projects_by_status = {stat["_id"]: stat["count"] for stat in status_stats}
        
        # 按优先级分组统计
        pipeline = [
            {"$match": query},
            {"$group": {"_id": "$priority", "count": {"$sum": 1}}}
        ]
        priority_stats = await db.projects.aggregate(pipeline).to_list(length=None)
        projects_by_priority = {stat["_id"]: stat["count"] for stat in priority_stats}
        
        # 按分类分组统计
        pipeline = [
            {"$match": query},
            {"$group": {"_id": "$category", "count": {"$sum": 1}}}
        ]
        category_stats = await db.projects.aggregate(pipeline).to_list(length=None)
        projects_by_category = {stat["_id"]: stat["count"] for stat in category_stats}
        
        stats_data = {
            "total_projects": total_projects,
            "active_projects": active_projects,
            "completed_projects": completed_projects,
            "overdue_projects": overdue_projects,
            "projects_by_status": projects_by_status,
            "projects_by_priority": projects_by_priority,
            "projects_by_category": projects_by_category
        }
        
        return success_response(
            data=stats_data,
            message="Project statistics retrieved successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=ErrorMessages.INTERNAL_ERROR,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.get("/{project_id}/activities", response_model=ApiResponse, summary="获取项目活动记录")
async def get_project_activities_endpoint(
    project_id: str,
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=200, description="每页大小"),
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """获取指定项目的活动记录"""
    try:
        data = await project_service.get_project_activities(
            db=db,
            project_id=project_id,
            current_user=current_user,
            page=page,
            size=size
        )
        return success_response(
            data=data,
            message="获取项目活动记录成功"
        )
    except ValueError as e:
        return error_response(
            error_type=ErrorTypes.NOT_FOUND,
            message=str(e),
            code=status.HTTP_404_NOT_FOUND
        )
    except PermissionError as e:
        return error_response(
            error_type=ErrorTypes.PERMISSION_ERROR,
            message=str(e),
            code=status.HTTP_403_FORBIDDEN
        )
    except Exception as e:
        logger.exception("Failed to fetch project activities")
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取项目活动记录失败: {str(e)}",
            code=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

@router.post("/{project_id}/pin", response_model=ApiResponse, summary="置顶项目")
async def pin_project(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """置顶项目"""
    try:
        # 验证ObjectId格式
        try:
            project_object_id = ObjectId(project_id)
        except Exception:
            return error_response(
                error_type=ErrorTypes.INVALID_PARAMETER,
                message="Invalid project ID format",
                code=400,
                request_id=getattr(request.state, 'request_id', None)
            )
        
        # 检查项目是否存在
        project = await db.projects.find_one({"_id": project_object_id})
        if not project:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="Project not found",
                code=404,
                request_id=getattr(request.state, 'request_id', None)
            )
        
        # 检查项目成员权限
        from app.services.permission_service import PermissionService
        try:
            project_id_str = str(project_object_id) if isinstance(project_object_id, ObjectId) else project_id
            has_access = await PermissionService.check_project_member_permission(
                project_id_str,
                current_user,
                db,
                "project:read"
            )
            if not has_access:
                return error_response(
                    error_type=ErrorTypes.PERMISSION_ERROR,
                    message="Not enough permissions to pin this project",
                    code=403,
                    request_id=getattr(request.state, 'request_id', None)
                )
        except Exception:
            return error_response(
                error_type=ErrorTypes.PERMISSION_ERROR,
                message="Not enough permissions to pin this project",
                code=403,
                request_id=getattr(request.state, 'request_id', None)
            )
        
        # 检查是否已经置顶（幂等操作：如果已置顶，直接返回成功）
        existing_pin = await db.user_project_pins.find_one({
            "user_id": user_id,
            "project_id": project_object_id
        })
        
        if existing_pin:
            # 已经置顶，返回成功（幂等操作）
            return success_response(
                message="Project already pinned",
                request_id=getattr(request.state, 'request_id', None)
            )
        
        # 添加置顶
        await db.user_project_pins.insert_one({
            "user_id": user_id,
            "project_id": project_object_id,
            "created_at": datetime.utcnow()
        })
        
        return success_response(
            message="Project pinned successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except Exception as e:
        logger.exception("Failed to pin project")
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"置顶项目失败: {str(e)}",
            code=500,
            request_id=getattr(request.state, 'request_id', None)
        )

@router.delete("/{project_id}/pin", response_model=ApiResponse, summary="取消置顶项目")
async def unpin_project(
    request: Request,
    project_id: str,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Any:
    """取消置顶项目"""
    try:
        # 验证ObjectId格式
        try:
            project_object_id = ObjectId(project_id)
        except Exception:
            return error_response(
                error_type=ErrorTypes.INVALID_PARAMETER,
                message="Invalid project ID format",
                code=400,
                request_id=getattr(request.state, 'request_id', None)
            )
        
        user_id = ObjectId(current_user.get("user_id"))
        
        # 删除置顶记录（幂等操作：如果未置顶，直接返回成功）
        result = await db.user_project_pins.delete_one({
            "user_id": user_id,
            "project_id": project_object_id
        })
        
        if result.deleted_count == 0:
            # 未置顶，返回成功（幂等操作）
            return success_response(
                message="Project not pinned",
                request_id=getattr(request.state, 'request_id', None)
            )
        
        return success_response(
            message="Project unpinned successfully",
            request_id=getattr(request.state, 'request_id', None)
        )
        
    except Exception as e:
        logger.exception("Failed to unpin project")
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"取消置顶项目失败: {str(e)}",
            code=500,
            request_id=getattr(request.state, 'request_id', None)
        )